<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
</html>

<script>
  // ### 1)定义规则
  // - 你定义在哪一个作用域下的变量，就是哪一个作用域的私有变量
  // - 该变量只能在该作用域及其后代作用域中使用

  // var a = 3; // 全局作用域
  // function fn() {
  //   // 局部作用域
  //   console.log(a);
  // }

  // function fn2() {
  //   var b = 5;
  //   function fn3() {
  //     console.log(b);
  //     console.log(333);
  //   }
  //   console.log(b);
  //   fn3();
  // }
  // fn2();
  // console.log(b);









  // ### 2) 访问规则
  // - 当我想获取一个变量的值的时候，我们管这个行为叫做 **访问**
  // - 获取变量的规则： 
  //   - 首先，在自己的作用域内部查找，如果有，就直接拿来使用
  //   - 如果没有，就去上一级作用域查找，如果有，就拿来使用
  //   - 如果没有，就继续去上一级作用域查找，依次类推
  //   - 如果一直到全局作用域都没有这个变量，那么就会直接报错（该变量 is not defined）

  // - 变量的访问规则 也叫做 作用域的查找机制
  // - 作用域的查找机制只能是向上找，不能向下找

  // 这个访问的过程，称之为作用域链

  // var x = 100;
  // function fn4() {
  //   var x = 200;
  //   console.log(x); // 200
  // }
  // fn4();
  // console.log(x); // 100











  // ### 3) 赋值规则
  // - 当你想给一个变量赋值的时候，那么就先要找到这个变量，在给他赋值
  // - 变量赋值规则：
  //   - 先在自己作用域内部查找，有就直接赋值
  //   - 没有就去上一级作用域内部查找，有就直接赋值
  //   - 在没有再去上一级作用域查找，有就直接赋值
  //   - 如果一直找到全局作用域都没有，那么就把这个变量定义为全局变量，在给他赋值

  // var num = 100;
  // function fn5() {
  //   var num = 200;
  // }
  // fn5();
  // console.log(num); // 100 因为200是有函数的局部作用域的，没有办法获取到

  // var num = 100;
  // function fn5() {
  //   num = 200;
  // }
  // fn5();
  // console.log(num); // 200 因为函数里面没有var关键字，所以只能去修改全局作用域下的num

  // var num = 100;
  // function fn5() {
  //   var num = 500;
  //   num = 200;
  // }
  // fn5();
  // console.log(num); // 100 先在自己作用域内部查找，有就直接赋值, 所以改的是97行的500->200

  // num = 100;
  // console.log(window); // 如果一直找到全局作用域都没有，那么就把这个变量定义为全局变量，在给他赋值
  // function fn6() {
  //   num = 800;
  // }
  // fn6();
  // console.log(num);
  // console.log(window);
</script>